package ar.edu.uba.fi.jmit.monitorengine.core;

import ar.edu.uba.fi.jmit.integrationcommons.Event;
import ar.edu.uba.fi.jmit.integrationcommons.EventPriority;
import ar.edu.uba.fi.jmit.monitorengine.Constants;
import ar.edu.uba.fi.jmit.monitorengine.MonitorEngineTestCase;
import ar.edu.uba.fi.jmit.monitorengine.ResourceProperties;
import ar.edu.uba.fi.jmit.monitorengine.core.monitormanager.AppTypeManager;
import ar.edu.uba.fi.jmit.monitorengine.exception.MonitorEngineException;
import ar.edu.uba.fi.jmit.monitorengine.mock.ConfigurationManagerMock;
import ar.edu.uba.fi.jmit.monitorengine.mock.MockMonitor1;
import ar.edu.uba.fi.jmit.monitorengine.mock.MockMonitor2;

public class AppTypeManagerTestCase extends MonitorEngineTestCase {

	public void testGetMonitor() {
		ConfigurationManagerMock.useMockConfigurationManager();
		ConfigurationManagerMock.addMonitorApplication("test1", "application1");
		ConfigurationManagerMock.addMonitorApplication("test2", "application2");
		AppTypeManager manager = new AppTypeManager();
		MockMonitor1.restart();
		MockMonitor2.restart();
		try {
			Event event = createEvent("test1");
			MockMonitor1 monitor = (MockMonitor1) manager.getMonitor(MockMonitor1.class.getName(), event);
			assertNotNull(monitor);
			monitor.doExecute(event);
			assertEquals(1, MockMonitor1.getExecutedEvents().size());
			MockMonitor1 monitor2 = (MockMonitor1) manager.getMonitor(MockMonitor1.class.getName(), event);
			assertEquals(monitor, monitor2);
			
			MockMonitor1 monitor3 = (MockMonitor1) manager.getMonitor(MockMonitor1.class.getName(), createEvent("test2"));
			assertNotSame(monitor, monitor3);
			assertNotSame(monitor2, monitor3);
			event.setSource("");
			event.setPriority(EventPriority.ALERT);
			event.addData(ResourceProperties.getProperty(Constants.EVENT_MONITOR_NAME_KEY), "test2");
			MockMonitor1 monitor4 = (MockMonitor1) manager.getMonitor(MockMonitor1.class.getName(), event);
			assertEquals(monitor3, monitor4);
			assertNotSame(monitor4, monitor);
			assertNotSame(monitor4, monitor2);
			
			MockMonitor2 monitor5 = (MockMonitor2) manager.getMonitor(MockMonitor2.class.getName(), createEvent("test1"));
			assertNotSame(monitor5, monitor);
			assertNotSame(monitor5, monitor3);
			
			MockMonitor2 monitor6 = (MockMonitor2) manager.getMonitor(MockMonitor2.class.getName(), createEvent("test1"));
			assertEquals(monitor6, monitor5);
			assertEquals(manager.getMonitor(MockMonitor1.class.getName(), createEvent("test1")),
					manager.getMonitor(MockMonitor1.class.getName(), createEvent("test1")));
			assertEquals(manager.getMonitor(MockMonitor1.class.getName(), createEvent("test2")),
					manager.getMonitor(MockMonitor1.class.getName(), createEvent("test2")));
			assertEquals(manager.getMonitor(MockMonitor2.class.getName(), createEvent("test1")),
					manager.getMonitor(MockMonitor2.class.getName(), createEvent("test1")));
			assertEquals(manager.getMonitor(MockMonitor2.class.getName(), createEvent("test2")),
					manager.getMonitor(MockMonitor2.class.getName(), createEvent("test2")));
			assertNotSame(manager.getMonitor(MockMonitor1.class.getName(), createEvent("test1")),
					manager.getMonitor(MockMonitor2.class.getName(), createEvent("test1")));
			assertNotSame(manager.getMonitor(MockMonitor2.class.getName(), createEvent("test1")),
					manager.getMonitor(MockMonitor2.class.getName(), createEvent("test2")));
		} catch (MonitorEngineException e) {
			fail(e);
		}
	}
	
	public void testRemove() {
		ConfigurationManagerMock.useMockConfigurationManager();
		ConfigurationManagerMock.addMonitorApplication("test1", "application1");
		ConfigurationManagerMock.addMonitorApplication("test2", "application2");
		AppTypeManager manager = new AppTypeManager();
		MockMonitor1.restart();
		MockMonitor2.restart();
		try {
			Monitor monitor = manager.getMonitor(MockMonitor1.class.getName(), createEvent("test1"));
			Monitor monitor2 = manager.getMonitor(MockMonitor1.class.getName(), createEvent("test1"));
			assertEquals(monitor, monitor2);
			
			Monitor monitor3 = manager.getMonitor(MockMonitor1.class.getName(), createEvent("test2"));
			Monitor monitor4 = manager.getMonitor(MockMonitor1.class.getName(), createEvent("test2"));
			assertEquals(monitor3, monitor4);
			
			manager.removeMonitor("test1");
			Monitor newMonitor1 = manager.getMonitor(MockMonitor1.class.getName(), createEvent("test1"));
			assertNotSame(monitor, newMonitor1);
			
			manager.removeMonitor("test2");
			Monitor newMonitor2 = manager.getMonitor(MockMonitor1.class.getName(), createEvent("test2"));
			assertNotSame(monitor3, newMonitor2);
			
		} catch (MonitorEngineException e) {
			fail(e);
		}
	}
	
	private Event createEvent(String monitorName) {
		Event event = new Event();
		event.setSource("SingletonTypeManagerTestCase");
		event.setPriority(EventPriority.NORMAL);
		event.addData(ResourceProperties.getProperty(Constants.EVENT_MONITOR_NAME_KEY), monitorName);
		return event;
	}
}
